<?php
/**
 * 描述：1688Api接口封装
 * 作者：Zoro.Zhu
 */
class model_api_aliApi extends L {

    public static $apiUrl = 'https://gw.open.1688.com/openapi/';

    /**
     * 描述 : 签名串组规则
     * 作者 : Zoro.Zhu
     */
    public static function apiSign($codeArr, $apiUrl, $appSecret) {
        ksort($codeArr);
        foreach ($codeArr as $key => $val) {
            $apiUrl .= $key.$val;
        }
        return strtoupper(bin2hex(hash_hmac("sha1", $apiUrl, $appSecret, true)));
    }

    /**
     * 描述 : 调用1688的API接口，获取TOKEN信息
     * 参数 : {
     *           'code' : code,
     *           'appKey' : 用户ID,
     *           'appSecret' : 用户密码,
     *       }
     * 作者 : Zoro.Zhu
     */
    public static function codeToken($code,$appKey,$secret) {
        $apiFunc = "param2/1/system.oauth2/getToken/{$appKey}";
        $codeArr = array(
            "client_id" => $appKey,
            "grant_type" => "authorization_code",
            "client_secret" => $secret,
            "code" => $code,
            "need_refresh_token" => 'true',
        );
        $signature = self::apiSign($codeArr, self::$apiUrl.$apiFunc, $secret);
        $data = array(
            "grant_type" => "authorization_code",
            "code" => $code,
            "need_refresh_token" => 'true',
            "client_id" => $appKey,
            "client_secret" => $secret,
            "_aop_signature" => $signature
        );
        $data = http_build_query($data);
        $res = of_base_com_net::request(self::$apiUrl.$apiFunc, array('post' => $data));
        if(!empty($res['state'])){
            return json_decode($res['response'], true);
        }
    }

    /**
     * 描述 : 调用1688的API接口，获取TOKEN信息
     * 参数 : {
     *           'refreshToken' : 长久TOKEN,
     *           'appKey' : 用户ID,
     *           'appSecret' : 用户密码,
     *       }
     * 作者 : Zoro.Zhu
     */
    public static function getAccessToken($params) {
        $apiFunc = "param2/1/system.oauth2/getToken/{$params['appKey']}";
        $codeArr = array(
            "client_id" => $params['appKey'],
            "grant_type" => "refresh_token",
            "client_secret" => $params['appSecret'],
            "refresh_token" => $params['refreshToken'],
        );
        $signature = self::apiSign($codeArr, self::$apiUrl.$apiFunc, $params['appSecret']);
        $data = array(
            "grant_type" => "refresh_token",
            "refresh_token" => $params['refreshToken'],
            "client_id" => $params['appKey'],
            "client_secret" => $params['appSecret'],
            "_aop_signature" => $signature
        );
        $data = http_build_query($data);
        $res = of_base_com_net::request(self::$apiUrl.$apiFunc, array('post' => $data));
        if($res['state']){
            $response = json_decode($res['response'], true);
            if(!empty($response['access_token'])){
                L::sql("UPDATE `vs_account` 
                SET `accessToken` = '{$response['access_token']}' 
                WHERE
                    `account` = '{$params['account']}'");
                $params['accessToken'] = $response['access_token'];
                $params['count'] = !empty($params['count']) ? 2 : 1;
                return $params;
            }
        }
        return false;
    }

    /**
     * 描述 : 获取产品详情信息
     * 作者 : Zoro.Zhu
     */
    public static function getProduct($params){
        $set = array(
            'access_token' => $params['accessToken'],
            'productID' => $params['productId'],
            'webSite' => '1688'
        );
        $apiFunc = 'param2/1/com.alibaba.product/alibaba.agent.product.get/'.$params['appKey'];
        $url = self::$apiUrl.$apiFunc;
        $set['_aop_signature'] = self::apiSign($set,$apiFunc,$params['appSecret']);
        $data = http_build_query($set);
        $result = of_base_com_net::request($url, array('post'=>$data));
        if($result['state']){
            return json_decode($result['response'], true);
        }
        return false;
    }

    /**
     * 描述 : 获取类目信息
     * 作者 : Zoro.Zhu
    **/
    public static function getCatInfo($params){
        $set = array(
            'access_token' => $params['accessToken'],
            'categoryID' => $params['categoryId'],
        );
        $apiFunc = 'param2/1/com.alibaba.product/alibaba.category.get/'.$params['appKey'];
        $url = self::$apiUrl.$apiFunc;
        $set['_aop_signature'] = self::apiSign($set,$apiFunc,$params['appSecret']);
        $data = http_build_query($set);
        $result = of_base_com_net::request($url, array('post'=>$data));
        if($result['state']){
            return json_decode($result['response'], true);
        }
        return false;
    }

    /**
     * 描述 : 快速创建阿里订单
     * 参数 : {
     *          'aliPay' : {
     *              'accessToken' : TOKEN,
     *              'appKey' : 用户ID,
     *              'appSecret' : 用户密码,
     *          },
     *          'purchaseInfo' : {
     *              'offerId' : 阿里产品ID,
     *              'specId' : 对应ID,
     *              'waitQty' : 数量,
     *          },
     *          'warehouse' : {
     *              'fullName' : 收货人姓名,
     *              'mobile' : 手机,
     *              'phone' : 电话,
     *              'postCode' : 邮编,
     *              'cityText' : 市文本,
     *              'provinceText' : 省份文本,
     *              'areaText' : 区文本,
     *              'townText' : 镇文本,
     *              'address' : 街道地址,
     *              'districtCode' : 地址编码,
     *              'warehouse' : 仓库名称,
     *              'addressId' : 收货地址id,
     *          },
     *          'remark' : 备注信息
     *       },
     * 作者 : Zoro.Zhu
     */
    public static function fastCreateOrder($params) {
        $apiUrl = "param2/1/com.alibaba.trade/alibaba.trade.createCrossOrder/{$params['aliPay']['appKey']}";
        $codeArr = array(
            "access_token" => $params['aliPay']['accessToken'],
            "flow" => "saleproxy", //流程 general(创建大市场订单)，saleproxy(创建代销市场订单)
            "message" => $params['remark'], //买家留言
            "cargoParamList" => json_encode($params['purchaseInfo']), //商品信息
            "addressParam" => json_encode($params['warehouse']), //收货地址信息
            'tradeType' => 'fxassure', //付款类型
        );
        $codeArr['_aop_signature'] = self::apiSign($codeArr, $apiUrl, $params['aliPay']['appSecret']);
        $data = http_build_query($codeArr);
        $res =  of_base_com_net::request(self::$apiUrl.$apiUrl, array('post' => $data));
        if(!empty($res['state'])){
            $info = json_decode($res['response'], true);
            if(!empty($info['success'])){
                return $info['result'];
            }else{
                return $info['message'];
            }
        }
        return false;
    }

    /**
     * 描述 : 获取订单详情
     * 参数 : {
     *          'aliPay' : {
     *              'accessToken' : TOKEN,
     *              'appKey' : 用户ID,
     *              'appSecret' : 用户密码,
     *          },
     *          'buyOrder' : 付款单号
     *       }
     * 作者 : Zoro.Zhu
     */
    public static function getOrderInfo($params) {
        $apiUrl = "param2/1/com.alibaba.trade/alibaba.trade.get.buyerView/{$params['aliPay']['appKey']}";
        preg_match_all('/\d+/', $params['buyOrder'], $arr);
        $buyOrder = join('', $arr[0]);
        $codeArr = array(
            "access_token" => $params['aliPay']['accessToken'],
            'orderId' => $buyOrder,
            'webSite' => '1688'
        );
        $codeArr['_aop_signature'] = self::apiSign($codeArr, $apiUrl, $params['aliPay']['appSecret']);
        $data = http_build_query($codeArr);
        $res =  of_base_com_net::request(self::$apiUrl.$apiUrl, array('post' => $data));
//        echo $params['aliPay']['accessToken'] . '->' . $params['buyOrder'] . '<br>';
//        p($res);exit;
        if(!empty($res['state'])){
            //去除emoji表情，防止json_decode失败
            $res['response'] = iconv('UTF-8', 'UTF-8//IGNORE', $res['response']);
            $info = json_decode($res['response'], true);
            if(!empty($info['success'])){
                return !empty($info['result']) ? $info['result'] : [];
            }
        } else if(!empty($res['errstr'])) {
            $res = json_decode($res['errstr'], true);
            if($res['error_code'] == 401){
                $token = self::getAccessToken($params['aliPay']);
                if(!empty($token)) {
                    if($token['count'] > 1){
                        return false;
                    } else {
                        $params['aliPay'] = $token;
                        return self::getOrderInfo($params);
                    }
                }
            }
        }
        return false;
    }

    /**
     * 描述 : 电话通知接口
     * 作者 : Zoro.Zhu
     */
    public static function phoneNotification($phone, $ttsCode, $ttsParam, $CalledShowNumber = ''){
        $apiUrl = "http://dyvmsapi.aliyuncs.com/?";
        $appkeyId = 'LTAI4G2MFxBj4HcG54RmQLxK';
        $accessKeySecret = 'YjoaFMveRo5NpWHCLwTh3OJqKjZcii';
        $codeArr = [
            'Action' => 'SingleCallByTts',
            'CalledNumber' => $phone,//被叫号码。仅支持中国内地号码。 一次请求仅支持一个被叫号
            'CalledShowNumber' => $CalledShowNumber,//被叫显号
            'TtsCode' => $ttsCode, //模版ID
            'TtsParam' => json_encode($ttsParam),//模板中的变量参数，格式为JSON
            'PlayTimes' => 3,//语音文件的播放次数，取值范围为1~3
            'Volume' => 88,//语音文件播放的音量。取值范围为0~100，默认为100。
            'Speed' => 10,//语速控制，取值范围：-500~500
            'SignatureMethod' => 'HMAC-SHA1',
            'Format' => 'JSON',
            'Version' => '2017-05-25',
            'AccessKeyId' => $appkeyId,
            'Timestamp' => date('Y-m-d\TH:i:s\Z', time() - 3600 * 8),
            'SignatureVersion' => '1.0',
            'SignatureNonce' => of_base_com_str::uniqid(),
        ];
        $codeArr['Signature'] = self::apiYunSign($codeArr, $accessKeySecret);
        ksort($codeArr);
        $data = http_build_query($codeArr);
        $res =  of_base_com_net::request($apiUrl . $data);
        if($res['state']){
            $response = json_decode($res['response'], true);
            return $response;
        }
    }

    /**
     * 描述 : 签名串组规则
     * 作者 : Zoro.Zhu
     */
    public static function apiYunSign($parameters, $accessKeySecret) {
        // 将参数Key按字典顺序排序
        ksort($parameters);
        // 生成规范化请求字符串
        $canonicalizedQueryString = '';
        foreach($parameters as $key => $value)
        {
            $canonicalizedQueryString .= '&' . self::urlStr($key)
                . '=' . self::urlStr($value);
        }
        // 生成用于计算签名的字符串 stringToSign
        $stringToSign = 'GET&%2F&' . self::urlStr(substr($canonicalizedQueryString, 1));
        // 计算签名，注意accessKeySecret后面要加上字符'&'
        $signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
        return $signature;
    }

    /**
     * 描述 : 处理字符
     * 作者 : Zoro.Zhu
     */
    public static function urlStr($str){
        // 使用urlencode编码后，将"+","*","%7E"做替换即满足ECS API规定的编码规范
        $res = urlencode($str);
        $res = preg_replace('/\+/', '%20', $res);
        $res = preg_replace('/\*/', '%2A', $res);
        $res = preg_replace('/%7E/', '~', $res);
        return $res;
    }
}